#include "stdafx.h"
#include "Config.h"

#include <iostream>
#include <fstream>

Config* Config::mInstance = 0;

bool Config::createConfig(const string & fileName) {
	if( mInstance == 0) {
		mInstance = new Config();
		if(mInstance->load(fileName)) {
			return true;
		} else {
			delete mInstance;
			mInstance = 0;
			return false;
		}
	}
	return true;
}

Config::Config() {
}


Config::~Config() {
}

bool Config::load(const string & fileName) {
	ifstream in;
	in.open(fileName);
	string line;
	string key, val;
	int pos;
	typedef pair<string, string> Str_Pair;
	if( in.good() ) {
		while( !in.eof() ) {
			getline(in, line);
			pos = line.find_first_not_of(" ");
			if (pos == string::npos) continue;
			line = line.substr(pos, line.length()-pos);
			pos = line.find_first_of("#");
			if(pos == 0) continue;
			if(pos != string::npos) {
				line = line.substr(0, pos);
			}
			pos = line.find_last_not_of(" ");
			if( (pos + 1) < (int)line.length() ) {
				line = line.substr(0, pos+1);
			}
			pos = line.find_first_of("=");
			if(pos == string::npos && pos == line.length()-1) continue;
			key = line.substr(0, pos);
			val = line.substr(pos+1, line.length()-pos-1);
			mMap.insert(Str_Pair(key, val));
		}
		return true;
	} else {
		return false;
	}

}

bool Config::getValue(const string &key, string *s) {
	map<string, string>::const_iterator it = mMap.find(key);
	if( it == mMap.end() ) return false;
	*s = it->second;
	return true;
}
bool Config::getValue(const string &key, double *v) {
	string s;
	if(getValue(key, &s)){
		*v = atof(s.c_str());
		return true;
	} else {
		return false;
	}
}
bool Config::getValue(const string &key, int *i) {
	string s;
	if(getValue(key, &s)){
		*i = atoi(s.c_str());
		return true;
	} else {
		return false;
	}
}
bool Config::getValue(const string &key, long *l) {
	string s;
	if(getValue(key, &s)){
		*l = atol(s.c_str());
		return true;
	} else {
		return false;
	}
}

string Config::getValue(const string &key, const string & d) {
	string v;
	if( getValue(key, &v) ) 
		return v;
	else return d;
}
int Config::getValue(const string &key, int d) {
	int v;
	if( getValue(key, &v) ) return v;
	else return d;
}
double Config::getValue(const string &key, double d) {
	double v;
	if( getValue(key, &v) ) return v;
	else return d;
}
long Config::getValue(const string &key, long d) {
	long v;
	if( getValue(key, &v) ) return v;
	else return d;
}